
<div>
    <Search Value="@searchKey" Placeholder="Search.." ValueChanged="PrcessSearch" />
    <Tree Nodes="TreeNodes"></Tree>
</div>

@code{

    string searchKey;

    void PrcessSearch(string newval)
    {
        searchKey = newval.Trim();
        CheckNodesRecursive(TreeNodes);
    }

    bool CheckNodesRecursive(List<TreeNode> nodes)
    {
        int matches = 0;

        foreach (TreeNode node in nodes)
        {
            if (!string.IsNullOrEmpty(searchKey) && node.Text.Contains(searchKey, StringComparison.OrdinalIgnoreCase))
                matches++;

            if (!node.HasChildNodes)
                continue;

            node.IsExpanded = CheckNodesRecursive(node.Nodes);
            if (node.IsExpanded)
                matches++;
        }

        return matches != 0;
    }


    List<TreeNode> _treeNodes;

    public List<TreeNode> TreeNodes
    {
        get
        {
            if (_treeNodes != null)
                return _treeNodes;

            _treeNodes = new List<TreeNode>();
            MakeSampleData(_treeNodes, "0", 0);

            return _treeNodes;
        }
    }

    RenderFragment RenderNodeTemplate(TreeNode node)
    {
        int index = string.IsNullOrEmpty(searchKey) ? -1 : node.Text.IndexOf(searchKey, StringComparison.OrdinalIgnoreCase);
        if (index == -1)
            return (b) => { b.AddContent(0, node.Text); };
        return (b) =>
        {
            if (index != 0)
                b.AddContent(0, node.Text.Substring(0, index));
            b.AddMarkupContent(1, "<span class='site-tree-search-value' style='color:orange'>" + searchKey + "</span>");
            if (index + searchKey.Length < node.Text.Length)
                b.AddContent(2, node.Text.Substring(index + searchKey.Length));
        };
    }


    void MakeSampleData(List<TreeNode> nodes, string ptext, int level)
    {
        for (int index = 0; index < 3; index++)
        {
            TreeNode subnode = new TreeNode();
            subnode.Text = ptext + "-" + index;
            subnode.NodeTemplate = this.RenderNodeTemplate;
            nodes.Add(subnode);

            if (index < 2 && level < 2)
            {
                MakeSampleData(subnode.Nodes, subnode.Text, level + 1);
            }
        }
    }
}


